package cn.javaxc.mvcwork.util.io;
import cn.javaxc.mvcwork.framework.actions.TActionContext;
import cn.javaxc.mvcwork.util.common.StringUtils;
import java.io.*;
import java.net.*;
import java.util.zip.*;
import javax.servlet.ServletOutputStream;




public class FileDownload {

  private File downloadFile = null;
  private String displayName = null;


  
  public void setFullPath(String tmp) {
	if(System.getProperty("DEBUG")!=null)System.out.println(this.getClass().getName()+".setFullPath "+tmp);
    downloadFile = new File(tmp);

  }



  
  public void setDisplayName(String tmp) {
    this.displayName = tmp;
  }


  



  
  public String getDisplayName() {
    return displayName;
  }


  
  public FileDownload() {
  }


  
  public boolean fileExists() {
    return downloadFile.exists();
  }


  public static String getContentType(String filename) {
    String contentType = "application/octet-stream";
    if (filename.endsWith(".bmp")) {
      contentType = "image/bmp";
    } else if (filename.endsWith(".css")) {
      contentType = "text/plain";
    } else if (filename.endsWith(".doc")) {
      contentType = "application/msword";
    } else if (filename.endsWith(".dot")) {
      contentType = "application/msword";
    } else if (filename.endsWith(".eps")) {
      contentType = "application/postscript";
    } else if (filename.endsWith(".gif")) {
      contentType = "image/gif";
    } else if (filename.endsWith(".htm")) {
      contentType = "text/html";
    } else if (filename.endsWith(".html")) {
      contentType = "text/html";
    } else if (filename.endsWith(".java")) {
      contentType = "text/plain";
    } else if (filename.endsWith(".jpeg")) {
      contentType = "image/jpeg";
    } else if (filename.endsWith(".jpg")) {
      contentType = "image/jpeg";
    } else if (filename.endsWith(".js")) {
      contentType = "application/x-javascript";
    } else if (filename.endsWith(".mdb")) {
      contentType = "application/x-msaccess";
    } else if (filename.endsWith(".mid")) {
      contentType = "audio/mid";
    } else if (filename.endsWith(".midi")) {
      contentType = "audio/mid";
    } else if (filename.endsWith(".mp3")) {
      contentType = "audio/mpeg";
    } else if (filename.endsWith(".mpp")) {
      contentType = "application/vnd.ms-project";
    } else if (filename.endsWith(".pdf")) {
      contentType = "application/pdf";
    } else if (filename.endsWith(".png")) {
      contentType = "image/png";
    } else if (filename.endsWith(".pot")) {
      contentType = "application/vnd.ms-powerpoint";
    } else if (filename.endsWith(".pps")) {
      contentType = "application/vnd.ms-powerpoint";
    } else if (filename.endsWith(".ppt")) {
      contentType = "application/vnd.ms-powerpoint";
    } else if (filename.endsWith(".ps")) {
      contentType = "application/postscript";
    } else if (filename.endsWith(".rtf")) {
      contentType = "application/rtf";
    } else if (filename.endsWith(".sql")) {
      contentType = "text/plain";
    } else if (filename.endsWith(".tgz")) {
      contentType = "application/x-compressed";
    } else if (filename.endsWith(".tif")) {
      contentType = "image/tiff";
    } else if (filename.endsWith(".tiff")) {
      contentType = "image/tiff";
    } else if (filename.endsWith(".txt")) {
      contentType = "text/plain";
    } else if (filename.endsWith(".log")) {
      contentType = "text/plain";
    } else if (filename.endsWith(".wav")) {
      contentType = "audio/x-wav";
    } else if (filename.endsWith(".wks")) {
      contentType = "application/vnd.ms-works";
    } else if (filename.endsWith(".wps")) {
      contentType = "application/vnd.ms-works";
    } else if (filename.endsWith(".xls")) {
      contentType = "application/vnd.ms-excel";
    } else if (filename.endsWith(".xml")) {
      contentType = "text/xml";
    } else if (filename.endsWith(".xsl")) {
      contentType = "text/xml";
    } else if (filename.endsWith(".zip")) {
      contentType = "application/x-zip-compressed";
    } else if (filename.endsWith(".vcf")) {
      contentType = "text/x-vcard";
    } else if (filename.endsWith(".csv")) {
      contentType = "text/csv";
    } else if (filename.endsWith("readme")) {
      contentType = "text/plain";
    } else if (filename.endsWith(".java")) {
      contentType = "text/plain";
    } else if (filename.endsWith(".jsp")) {
      contentType = "text/plain";
    }
    if (System.getProperty("DEBUG") != null)System.out.println("FileDownload-> File type: " + contentType);
    return contentType;
  }

  
  public void streamContent(TActionContext context) throws Exception {
	  long headerValue = context.getRequest().getDateHeader("If-Modified-Since");
      long lastModified = downloadFile.lastModified();
      if (headerValue != -1L)
      {
        if (lastModified < headerValue + 1000L)
        {
          context.getResponse().setStatus(304);
          return;
        }
      }
    context.getResponse().setDateHeader("Last-Modified", lastModified);
//	System.out.println(this.getClass().getName()+" "+context.getRequest().getHeader("If-Modified-Since"));
//	if (Boolean.valueOf(TTPSections.getClassProperty(FileDownload.class,"ETag","false"))){
//		String etag=context.getRequest().getHeader("If-None-Match");
//		if(etag!=null)
//		{
//		  context.getResponse().setStatus(304);
//		  return;
//		}else{
//			context.getResponse().setHeader("ETag","www.moonjsp.com");
//		}	
//	}
    if (downloadFile.getName().endsWith("TH")) {
      // NOTE: A temporary fix because all thumbnails (that are scaled)
      // are saved as JPG.  Actual size thumbnails match the original
      // filetype (PNG, GIF, JPG)
      context.getResponse().setContentType(getContentType(".jpg"));
    } else {
      context.getResponse().setContentType(getContentType(this.getDisplayName().toLowerCase()));
    }
    this.send(context);
  }


  
  public void sendFile(TActionContext context) throws Exception {
    sendFile(context, "application/octet-stream");
  }


  
  public void sendFile(TActionContext context, String contentType) throws Exception {
    context.getResponse().setContentType(contentType);
    if (contentType.startsWith("application")) {
      context.getResponse().setHeader(
          "Content-Disposition", "attachment; filename=\"" +URLEncoder.encode(displayName, "UTF-8")  + "\";");
      context.getResponse().setContentLength((int) downloadFile.length());
    }
    this.send(context);
  }


  public static void sendFile(TActionContext context, URL url, String contentType, String displayName) throws Exception {
    URLConnection urlConnection = url.openConnection();
    InputStream in = urlConnection.getInputStream();
    context.getResponse().setContentType(contentType);
    if (contentType.startsWith("application")) {
      context.getResponse().setHeader(
          "Content-Disposition", "attachment; filename=\"" +URLEncoder.encode(displayName, "UTF-8")  + "\";");
      context.getResponse().setContentLength(urlConnection.getContentLength());
    }
    ServletOutputStream outputStream = context.getResponse().getOutputStream();
    BufferedInputStream inputStream = new BufferedInputStream(in);
    byte[] buf = new byte[4 * 1024];
    // 4K buffer
    int len;
    while ((len = inputStream.read(buf, 0, buf.length)) != -1) {
      outputStream.write(buf, 0, len);
    }
    outputStream.flush();
    outputStream.close();
    inputStream.close();
  }


  
  public void sendFile(TActionContext context, byte[] bytes, String contentType) throws Exception {
    context.getResponse().setContentType(contentType);
    if (contentType.startsWith("application")) {
      context.getResponse().setHeader(
          "Content-Disposition", "attachment; filename=\"" +URLEncoder.encode(displayName, "UTF-8")  + "\";");
      context.getResponse().setContentLength(bytes.length);
    }
    ServletOutputStream ouputStream = context.getResponse().getOutputStream();
    ouputStream.write(bytes, 0, bytes.length);
    ouputStream.flush();
    ouputStream.close();
  }


  
  public void streamFile(TActionContext context, byte[] bytes, String contentType) throws Exception {
    context.getResponse().setContentType(contentType);
    ServletOutputStream outputStream = context.getResponse().getOutputStream();
    outputStream.write(bytes, 0, bytes.length);
    outputStream.flush();
    outputStream.close();
  }


  
  private void send(TActionContext context) throws Exception {
    ServletOutputStream outputStream = context.getResponse().getOutputStream();
    BufferedInputStream inputStream =
        new BufferedInputStream(new FileInputStream(downloadFile));
    byte[] buf = new byte[4 * 1024];
    // 4K buffer
    int len;
    while ((len = inputStream.read(buf, 0, buf.length)) != -1) {
      outputStream.write(buf, 0, len);
    }
    outputStream.flush();
    outputStream.close();
    inputStream.close();
  }


  
  public void sendTextAsFile(TActionContext context, String text) throws Exception {
    context.getResponse().setContentType("application/octet-stream");
    context.getResponse().setHeader("Content-Disposition", "attachment;filename=" +URLEncoder.encode(displayName, "UTF-8")  + ";");
    context.getResponse().setContentLength((int) text.length());

    ServletOutputStream outputStream = context.getResponse().getOutputStream();
    StringReader strReader = new StringReader(text);
    int data;
    while ((data = strReader.read()) != -1) {
      outputStream.write(data);
    }
    strReader.close();
    outputStream.close();
  }

  public void sendFileFromZip(TActionContext context, String zipFilename, String filename) throws IOException {
    context.getResponse().setContentType(getContentType(filename));
    ZipFile zipFile = new ZipFile(zipFilename);
    ZipEntry zipEntry = zipFile.getEntry(filename);
    // Note: ZipEntry must match the path that was saved in the path
    if (zipEntry == null) {
      zipEntry = zipFile.getEntry(filename.replace( "/", "\\"));
    }
    if (zipEntry == null) {
      zipEntry = zipFile.getEntry(filename.replace( "\\", "/"));
    }
    ServletOutputStream outputStream = context.getResponse().getOutputStream();
    BufferedInputStream inputStream =
        new BufferedInputStream(zipFile.getInputStream(zipEntry));
    byte[] buf = new byte[4 * 1024];
    // 4K buffer
    int len;
    while ((len = inputStream.read(buf, 0, buf.length)) != -1) {
      outputStream.write(buf, 0, len);
    }
    outputStream.flush();
    outputStream.close();
    inputStream.close();
    zipFile.close();
  }
}
